/*
 * Copyright (c) 2010-2020 Belledonne Communications SARL.
 *
 * This file is part of linphone-android
 * (see https://www.linphone.org).
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.newlink.building.activities.main.settings.viewmodels

import android.text.TextUtils
import android.widget.Toast
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.newlink.building.NL_App
import com.newlink.building.NL_App.Companion.coreContext
import com.newlink.building.NL_App.Companion.corePreferences
import com.newlink.building.R
import com.newlink.building.activities.main.settings.Module_Phone_SettingListenerStub
import com.newlink.building.utils.Module_Phone_Base64Utils
import com.newlink.building.utils.Module_Phone_Event
import org.linphone.core.AVPFMode
import org.linphone.core.Account
import org.linphone.core.AccountListenerStub
import org.linphone.core.Factory
import org.linphone.core.RegistrationState
import org.linphone.core.TransportType
import org.linphone.core.tools.Log

class AccountSettingsViewModelFactory(private val identity: String) :
    ViewModelProvider.NewInstanceFactory() {

    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        for (account in coreContext.core.accountList) {
            if (account.params.identityAddress?.asStringUriOnly() == identity) {
                return AccountSettingsViewModel(account) as T
            }
        }
        val defaultAccount = coreContext.core.defaultAccount
        if (defaultAccount != null) {
            return AccountSettingsViewModel(defaultAccount) as T
        }

        val firstAccount = coreContext.core.accountList.first()
        return AccountSettingsViewModel(firstAccount) as T
    }
}

class AccountSettingsViewModel(val account: Account) : Module_Phone_GenericSettingsViewModel() {

    val isDefault = MutableLiveData<Boolean>()

    val displayName = MutableLiveData<String>()

    val identity = MutableLiveData<String>()

    val iconResource = MutableLiveData<Int>()
    val iconContentDescription = MutableLiveData<Int>()
    val iconAllDescription = MutableLiveData<String>()

    lateinit var accountsSettingsListener: Module_Phone_SettingListenerStub

    val waitForUnregister = MutableLiveData<Boolean>()

    val accountRemovedEvent: MutableLiveData<Module_Phone_Event<Boolean>> by lazy {
        MutableLiveData<Module_Phone_Event<Boolean>>()
    }

    var passwordTmp: String = ""

    val displayUsernameInsteadOfIdentity = corePreferences.replaceSipUriByUsername

    private var accountToDelete: Account? = null

    val listener: AccountListenerStub = object : AccountListenerStub() {
        override fun onRegistrationStateChanged(
            account: Account,
            state: RegistrationState,
            message: String
        ) {
            Log.e("[Account Settings]  onRegistrationStateChanged  ${state.name}")
            if (state == RegistrationState.Cleared && account == accountToDelete) {
                Log.i("[Account Settings] Account to remove registration is now cleared")
                waitForUnregister.value = false
                deleteAccount(account)
            } else {
                update()
                if (state == RegistrationState.Ok) {
                    coreContext.contactsManager.updateLocalContacts()
                } else if (state == RegistrationState.Failed) {
                }
            }
        }
    }

    /* Settings part */

    fun saveAccountInfo(): Boolean {

        Log.e("jake", "===========save account=======")
        Log.e("jake", "-------${userName.value}--------")
        Log.e("jake", "-------${password.value}--------")
        Log.e("jake", "-------${domain.value}--------")
        Log.e("jake", "-------${port.value}--------")
        Log.e("jake", "========save account end======")
        var isIdentityDataChanged = false
        var isUserNameChanged = false
        var isUserIdChanged = false

        if (TextUtils.isEmpty(userName.value) ||
            TextUtils.isEmpty(password.value) ||
            TextUtils.isEmpty(domain.value) ||
            TextUtils.isEmpty(port.value) ||
            TextUtils.isEmpty(proxyServer.value) ||
            TextUtils.isEmpty(proxyPort.value)
        ) {
            Toast.makeText(
                coreContext.context,
                R.string.save_failed_empty_in_necessary,
                Toast.LENGTH_SHORT
            ).show()
            return false
        }
        val params = account.params.clone()
        val identity = params.identityAddress
        val authInfo = account.findAuthInfo()

        if (identity != null) {
            val newIdentityAddress = identity.clone()
            if (newIdentityAddress.username != userName.value) { // 修改用户
                Log.e("[yxd] modify username   userName:${userName.value}")
                newIdentityAddress.username = userName.value
                isIdentityDataChanged = true
                isUserNameChanged = true
            }
            authInfo?.let {
                if (it.userid != userId.value) {
                    isUserIdChanged = true
                }
            }

            val realPwd = authInfo?.password ?: getPasswordFromPref()
            if (realPwd != password.value || isUserNameChanged || isUserIdChanged) { // 修改密码,用户名更改必须重新设置密码,否则会出现authInfo为null的问题
                if (authInfo != null && authInfo.username == userName.value) { // 已存在用户
                    Log.e("[yxd] modify password  authInfo is not null  password:${password.value}  userId:${userId.value}")
                    val newAuthInfo = authInfo.clone()
                    newAuthInfo.password = password.value
                    newAuthInfo.userid = userId.value
                    if (newIdentityAddress.domain != domain.value) {
                        newAuthInfo.domain = domain.value
                    }
                    core.removeAuthInfo(authInfo)
                    core.addAuthInfo(newAuthInfo)
                } else { // 切换新用户要重新添加authInfo
                    Log.e("[yxd] modify password  create new authInfo   password:${password.value}")
                    val newAuthInfo = Factory.instance()
                        .createAuthInfo(
                            userName.value.orEmpty(),
                            userId.value,
                            password.value,
                            null,
                            null,
                            domain.value
                        )
                    core.addAuthInfo(newAuthInfo)
                }
                savePasswordToPref(password.value.toString())
                isIdentityDataChanged = true
            }

            if (newIdentityAddress.displayName.orEmpty() != displayName.value) { // 修改显示名
                Log.e("[yxd] modify displayName  displayName:${displayName.value}")
                newIdentityAddress.displayName = displayName.value
                isIdentityDataChanged = true
            }

            if (newIdentityAddress.domain != domain.value) { // 修改服务器地址
                Log.e("[yxd] modify domain   domain:${domain.value}")
                newIdentityAddress.domain = domain.value
                isIdentityDataChanged = true
            }

            if (newIdentityAddress.port != port.value?.toInt()) { // 修改端口号
                Log.e("[yxd] modify port   port:${port.value}")
                newIdentityAddress.port = port.value.orEmpty().toInt()
                isIdentityDataChanged = true
            }

            if (isIdentityDataChanged) {
                params.identityAddress = newIdentityAddress
            }

            val newServerAddress = params.serverAddress?.clone()
            if (newServerAddress != null) { // 设置代理服务器配置
                val safeProxyPort = proxyPort.value ?: "0"
                if (proxyServer.value != newServerAddress.domain || safeProxyPort.toInt() != newServerAddress.port) {
                    Log.e("[yxd] modify proxyAddress or  proxyPort  ${proxyServer.value}:${proxyPort.value}")
                    newServerAddress?.domain = proxyServer.value
                    newServerAddress?.port = safeProxyPort.toInt()
                }

                params.serverAddress = newServerAddress
            }

            transportIndex.value?.let {
                val type = TransportType.fromInt(it)
                if (type != params.transport) {
                    Log.e("[yxd] modify transport   transport:${type.name}")
                    params.transport = type
                }
            }

            expires.value?.let {
                if (it != params.expires) {
                    Log.e("[yxd] modify expires   expires:$it")
                    params.expires = it
                }
            }

            if (activate.value != params.isRegisterEnabled) {
                Log.e("[yxd] modify isRegisterEnabled   isRegisterEnabled:${activate.value}")
                params.isRegisterEnabled = activate.value == true
            }

            if (outboundProxy.value != params.isOutboundProxyEnabled) {
                Log.e("[yxd] modify isOutboundProxyEnabled   isOutboundProxyEnabled:${outboundProxy.value}")
                params.isOutboundProxyEnabled = outboundProxy.value == true
            }

            val natPolicy = core.createNatPolicy()
            natPolicy.stunServer = stunServer.value
            natPolicy.isStunEnabled = isTurnEnabled.value == true
//            natPolicy.isIceEnabled = ice.value == true
            params.natPolicy = natPolicy
            account.params = params

            natPolicy.isIceEnabled = ice.value == true

            params.natPolicy?.isTurnEnabled = isTurnEnabled.value == true
//            params.natPolicy?.isStunEnabled = isTurnEnabled.value == true
            params.natPolicy?.stunServerUsername = "admin"
//            params.natPolicy?.turnServerPassword = "123456"

            account.params = params
        }
        return true
    }

    private fun savePasswordToPref(pwd: String) {
        val encodeToString = Module_Phone_Base64Utils.encodeToString(pwd)
        corePreferences.storePresenceInNativePassword = encodeToString
    }

    private fun getPasswordFromPref(): String {

        val encodePassword = corePreferences.storePresenceInNativePassword.orEmpty()
        if (encodePassword.isNotEmpty()) {
            return Module_Phone_Base64Utils.decodeToString(encodePassword)
        }
        return ""
    }

    val userNameListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            val params = account.params.clone()
            val identity = params.identityAddress
            if (identity != null) {
                val newIdentityAddress = identity.clone()
                newIdentityAddress.username = newValue
                params.identityAddress = newIdentityAddress
                account.params = params
            } else {
                Log.e("[Account Settings] Account doesn't have an identity yet")

                val domain = params.domain
                val newIdentityAddress = Factory.instance().createAddress("sip:$newValue@$domain")
                if (newIdentityAddress != null) {
                    params.identityAddress = newIdentityAddress
                    account.params = params
                } else {
                    Log.e("[Account Settings] Failed to create identity address sip:$newValue@$domain")
                }
            }
        }
    }
    val userName = MutableLiveData<String>()

    val userIdListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            val authInfo = account.findAuthInfo()
            if (authInfo != null) {
                val newAuthInfo = authInfo.clone()
                newAuthInfo.userid = newValue
                core.removeAuthInfo(authInfo)
                core.addAuthInfo(newAuthInfo)
            } else {
                Log.e("[Account Settings] Failed to find the matching auth info")
            }
        }
    }
    val userId = MutableLiveData<String>()

    val passwordListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            val authInfo = account.findAuthInfo()
            if (authInfo != null) {
                val newAuthInfo = authInfo.clone()
                newAuthInfo.password = newValue
                core.removeAuthInfo(authInfo)
                core.addAuthInfo(newAuthInfo)
            } else {
                Log.w("[Account Settings] Failed to find the matching auth info")
                val params = account.params
                val identity = params.identityAddress
                if (identity != null && identity.username != null) {
                    val newAuthInfo = Factory.instance()
                        .createAuthInfo(
                            identity.username!!,
                            userId.value,
                            newValue,
                            null,
                            null,
                            identity.domain
                        )
                    core.addAuthInfo(newAuthInfo)
                } else {
                    Log.e("[Account Settings] Failed to find the user's identity, can't create a new auth info")
                }
            }
        }
    }
    val password = MutableLiveData<String>()

    val domainListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            val params = account.params.clone()
            val identity = params.identityAddress
            if (identity != null) {
                val authInfo = account.findAuthInfo()
                if (authInfo != null) {
                    val newAuthInfo = authInfo.clone()
                    newAuthInfo.domain = newValue
                    core.removeAuthInfo(authInfo)
                    core.addAuthInfo(newAuthInfo)
                } else {
                    Log.e("[Account Settings] Failed to find the matching auth info")
                }

                identity.domain = newValue
                params.identityAddress = identity
                account.params = params
            } else {
                Log.e("[Account Settings] Account doesn't have an identity yet")
            }
        }
    }
    val domain = MutableLiveData<String>()
    val port = MutableLiveData<String>()
    val transportType = MutableLiveData<Int>()

    val domain2 = MutableLiveData<String>()
    val port2 = MutableLiveData<String>()

    val displayNameListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            val params = account.params.clone()
            val identity = params.identityAddress
            if (identity != null) {
                identity.displayName = newValue
                params.identityAddress = identity
                account.params = params
            } else {
                Log.e("[Account Settings] Account doesn't have an identity yet")
            }
        }
    }
    // displayName mutable is above

    //    val disableListener = object : SettingListenerStub() {
//        override fun onBoolValueChanged(newValue: Boolean) {
//            val params = account.params.clone()
//            params.isRegisterEnabled = !newValue
//            account.params = params
//        }
//    }
    val activate = MutableLiveData<Boolean>()

    val isDefaultListener = object : Module_Phone_SettingListenerStub() {
        override fun onBoolValueChanged(newValue: Boolean) {
            if (newValue) {
                core.defaultAccount = account
            }
        }
    }
    // isDefault mutable is above

    private fun deleteAccount(account: Account) {
        val authInfo = account.findAuthInfo()
        if (authInfo != null) {
            Log.i("[Account Settings] Found auth info $authInfo, removing it.")
            core.removeAuthInfo(authInfo)
        } else {
            Log.w("[Account Settings] Couldn't find matching auth info...")
        }

        core.removeAccount(account)
        accountRemovedEvent.value = Module_Phone_Event(true)
    }

    val deleteListener = object : Module_Phone_SettingListenerStub() {
        override fun onClicked() {
            Log.e("jake", "....uok-------------------------------")
            accountToDelete = account

            val registered = account.state == RegistrationState.Ok
            waitForUnregister.value = registered

            if (core.defaultAccount == account) {
                Log.i("[Account Settings] Account was default, let's look for a replacement")
                for (accountIterator in core.accountList) {
                    if (account != accountIterator) {
                        core.defaultAccount = accountIterator
                        Log.i("[Account Settings] New default account is $accountIterator")
                        break
                    }
                }
            }

            val params = account.params.clone()
            params.isRegisterEnabled = false
            account.params = params

            if (!registered) {
                Log.w("[Account Settings] Account isn't registered, don't unregister before removing it")
                deleteAccount(account)
            }
        }
    }

    val clearUserData = object : Module_Phone_SettingListenerStub() {
        override fun onClicked() {
            userName.value = ""
            password.value = ""
            displayName.value = ""
            domain.value = ""
            port.value = ""
            proxyServer.value = ""
            proxyPort.value = ""
        }
    }

    val pushNotificationListener = object : Module_Phone_SettingListenerStub() {
        override fun onBoolValueChanged(newValue: Boolean) {
            val params = account.params.clone()
            params.pushNotificationAllowed = newValue
            account.params = params
        }
    }
    val pushNotification = MutableLiveData<Boolean>()
    val pushNotificationsAvailable = MutableLiveData<Boolean>()

    val overTimeIndex = MutableLiveData<Int>()
    val overTimeLabels = MutableLiveData<ArrayList<String>>()

    val overTimeListener = object : Module_Phone_SettingListenerStub() {
        override fun onListValueChanged(position: Int) {

            val newValue = overTimeLabels.value?.get(position)

            try {
                val params = account.params.clone()
                params.expires = newValue!!.toInt()
                account.params = params
            } catch (nfe: NumberFormatException) {
                Log.e("[Account Settings] Failed to set expires ($newValue): $nfe")
            }
        }
    }

    val transportListener = object : Module_Phone_SettingListenerStub() {
        override fun onListValueChanged(position: Int) {
            proxy.value = account.params.serverAddress?.asStringUriOnly()
            transportIndex.value = position
        }
    }
    val transportIndex = MutableLiveData<Int>()
    val transportLabels = MutableLiveData<ArrayList<String>>()

    val proxyListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            val params = account.params.clone()
            val address = Factory.instance().createAddress(newValue)
            if (address != null) {
                params.serverAddress = address
                account.params = params

                transportIndex.value = account.params.transport.toInt()
            } else {
                Log.e("[Account Settings] Couldn't parse address: $address")
            }
        }
    }
    val proxy = MutableLiveData<String>()

    val outboundProxyListener = object : Module_Phone_SettingListenerStub() {
        override fun onBoolValueChanged(newValue: Boolean) {
            val params = account.params.clone()
            params.isOutboundProxyEnabled = newValue
            account.params = params
        }
    }
    val outboundProxy = MutableLiveData<Boolean>()

    val stunServerListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            val params = account.params.clone()
            if (params.natPolicy == null) {
                Log.w("[Account Settings] No NAT Policy object in account params yet")
                val natPolicy = core.createNatPolicy()
                natPolicy.stunServer = newValue
                natPolicy.isStunEnabled = newValue.isNotEmpty()
                params.natPolicy = natPolicy
            } else {
                params.natPolicy?.stunServer = newValue
                params.natPolicy?.isStunEnabled = newValue.isNotEmpty()
            }
            if (newValue.isEmpty()) ice.value = false
            stunServer.value = newValue
            account.params = params
        }
    }
    val stunServer = MutableLiveData<String>()

    val iceListener = object : Module_Phone_SettingListenerStub() {
        override fun onBoolValueChanged(newValue: Boolean) {
            val params = account.params.clone()
            params.natPolicy?.isIceEnabled = newValue
            account.params = params
        }
    }
    val ice = MutableLiveData<Boolean>()

    val isTurnEnabled = MutableLiveData<Boolean>()

    val avpfListener = object : Module_Phone_SettingListenerStub() {
        override fun onBoolValueChanged(newValue: Boolean) {
            val params = account.params.clone()
            params.avpfMode = if (newValue) AVPFMode.Enabled else AVPFMode.Disabled
            account.params = params
        }
    }
    val avpf = MutableLiveData<Boolean>()

    val avpfRrIntervalListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            try {
                val params = account.params.clone()
                params.avpfRrInterval = newValue.toInt()
                account.params = params
            } catch (nfe: NumberFormatException) {
                Log.e("[Account Settings] Failed to set AVPF RR interval ($newValue): $nfe")
            }
        }
    }
    val avpfRrInterval = MutableLiveData<Int>()

    val expiresListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            try {
                val params = account.params.clone()
                params.expires = newValue.toInt()
                account.params = params
            } catch (nfe: NumberFormatException) {
                Log.e("[Account Settings] Failed to set expires ($newValue): $nfe")
            }
        }
    }
    val expires = MutableLiveData<Int>()

    val prefixListener = object : Module_Phone_SettingListenerStub() {
        override fun onTextValueChanged(newValue: String) {
            val params = account.params.clone()
            params.internationalPrefix = newValue
            account.params = params
        }
    }
    val prefix = MutableLiveData<String>()

    val dialPrefixListener = object : Module_Phone_SettingListenerStub() {
        override fun onBoolValueChanged(newValue: Boolean) {
            val params = account.params.clone()
            params.useInternationalPrefixForCallsAndChats = newValue
            account.params = params
        }
    }
    val dialPrefix = MutableLiveData<Boolean>()

    val escapePlusListener = object : Module_Phone_SettingListenerStub() {
        override fun onBoolValueChanged(newValue: Boolean) {
            val params = account.params.clone()
            params.isDialEscapePlusEnabled = newValue
            account.params = params
        }
    }
    val escapePlus = MutableLiveData<Boolean>()

    val linkPhoneNumberListener = object : Module_Phone_SettingListenerStub() {
        override fun onClicked() {
            linkPhoneNumberEvent.value = Module_Phone_Event(true)
        }
    }
    val linkPhoneNumberEvent = MutableLiveData<Module_Phone_Event<Boolean>>()

    val proxyServer = MutableLiveData<String>()
    val proxyPort = MutableLiveData<String>()

    init {
        Log.e("jake", "===[AccountSettingsViewModel]=== init{}")
        update()
        account.addListener(listener)
        initTransportList()
        initOverTimeList()
    }

    private fun setTransportPort(port: Int) {
        val transports = core.transports
        transports.udpPort = port
        transports.tcpPort = port
        transports.tlsPort = -1
        core.transports = transports
    }

//    private fun getTransportPort(): String {
// //        val transports = core.transports
// //        if (transports.udpPort > 0) return transports.udpPort
// //        return transports.tcpPort
//
//        Log.e("jake", "--> getDomain is  ${domain.value}")
//
//        val port = domain.value?.substringAfterLast(":")
//        Log.e("jake", "--> getPort is  $port")
//        return port ?: "5060"
//    }

    override fun onCleared() {
        destroy()
        super.onCleared()
    }

    fun destroy() {
        accountsSettingsListener = object : Module_Phone_SettingListenerStub() {}
        account.removeListener(listener)
    }

    fun checkChanged(): Boolean {
        val authInfo = account.findAuthInfo()
        val params = account.params.clone()

        var displayNameTmp = params.identityAddress?.displayName
        if (displayNameTmp == null) {
            displayNameTmp = ""
        }
        if (authInfo == null) {
            Log.e("jake  authInfo is null")
        }
        authInfo?.let {

            Log.e("jake  ${userName.value} : ${it.username} ")
            Log.e("jake  ${it.domain} : ${params.domain} ")
            Log.e("jake  $passwordTmp : ${password.value} ")
            Log.e("jake  ${port.value} : ${params.identityAddress?.port} ")
            Log.e("jake  $displayNameTmp : ${displayName.value} ")
            Log.e("jake  ${proxyServer.value} : ${params.serverAddress?.domain} ")
            Log.e("jake  ${proxyPort.value} : ${params.serverAddress?.port} ")

            if (
                userName.value != it.username ||
                it.domain != params.domain ||
                passwordTmp != password.value ||
                port.value != params.identityAddress?.port.toString() ||
//                displayName.value != params.identityAddress?.displayName ||
                displayName.value != displayNameTmp ||
                proxyServer.value != params.serverAddress?.domain ||
                proxyPort.value != params.serverAddress?.port.toString() ||
                expires.value != params.expires
            ) {
                return true
            }
        }

        return false
    }

    fun update() {
        isDefault.value = core.defaultAccount == account
        val params = account.params
        val identityAddress = params.identityAddress
        if (identityAddress != null) {
            displayName.value = identityAddress.displayName ?: ""
            identity.value = identityAddress.asStringUriOnly()
        }
        updateRegistrationState()
        userName.value = params.identityAddress?.username
        userId.value = account.findAuthInfo()?.userid
        password.value = account.findAuthInfo()?.password ?: getPasswordFromPref()
        passwordTmp = password.value!!
        domain.value = params.identityAddress?.domain
        port.value = params.identityAddress?.port.toString()
        activate.value = params.isRegisterEnabled
        pushNotification.value = params.pushNotificationAllowed
        pushNotificationsAvailable.value = core.isPushNotificationAvailable
        proxy.value = params.serverAddress?.asStringUriOnly()
        proxyServer.value = params.serverAddress?.domain
        proxyPort.value = params.serverAddress?.port.toString()

        outboundProxy.value = params.isOutboundProxyEnabled
        stunServer.value = params.natPolicy?.stunServer
        ice.value = params.natPolicy?.isIceEnabled
        isTurnEnabled.value = params.natPolicy?.isStunEnabled

        avpf.value = params.avpfMode == AVPFMode.Enabled
        avpfRrInterval.value = params.avpfRrInterval
        expires.value = params.expires
        prefix.value = params.internationalPrefix
        dialPrefix.value = params.useInternationalPrefixForCallsAndChats
        escapePlus.value = params.isDialEscapePlusEnabled
    }

    fun updateRegistrationState() {
        iconResource.value = when (account.state) {
            RegistrationState.Ok -> R.mipmap.sip_line_green
            RegistrationState.Failed -> R.mipmap.sip_line_red
            RegistrationState.Progress -> R.mipmap.sip_line_yellow
            else -> R.mipmap.sip_line_gray
        }
        val isRegisterEnabled = account.params.isRegisterEnabled
        if (!isRegisterEnabled) {
            iconResource.value = R.mipmap.sip_line_gray
        }
        iconContentDescription.value = when (account.state) {
            RegistrationState.Ok -> R.string.status_connected
            RegistrationState.Progress -> R.string.status_in_progress
            RegistrationState.Failed -> R.string.status_error
            else -> R.string.status_not_connected
        }
        iconAllDescription.value =
            coreContext.context.resources.getString(iconContentDescription.value!!)

        if (coreContext.core.defaultAccount?.state == RegistrationState.Failed) {
            val error = when (coreContext.core.defaultAccount?.errorInfo?.protocolCode) {
                100 -> NL_App.context.getString(R.string.status_error_code_info_100)
                500 -> NL_App.context.getString(R.string.status_error_code_info_500)
                503 -> NL_App.context.getString(R.string.status_error_code_info_503)
                504 -> NL_App.context.getString(R.string.status_error_code_info_504)
                else -> {
                    coreContext.core.defaultAccount?.errorInfo?.protocolCode.toString()
                }
            }

            if (!TextUtils.isEmpty(error)) {
                iconAllDescription.value =
                    "${coreContext.context.resources.getString(iconContentDescription.value!!)} , $error"
            }
        }
    }

    private fun initTransportList() {
        val labels = arrayListOf<String>()

        // Keep following in the same order as TransportType enum
        labels.add(prefs.getString(R.string.account_settings_transport_udp))
        labels.add(prefs.getString(R.string.account_settings_transport_tcp))
        labels.add(prefs.getString(R.string.account_settings_transport_tls))
        if (corePreferences.allowDtlsTransport) {
            labels.add(prefs.getString(R.string.account_settings_transport_dtls))
        }

        transportLabels.value = labels
        transportIndex.value = account.params.transport.toInt()
    }

    private fun initOverTimeList() {
        val labels = arrayListOf<String>()

        // Keep following in the same order as TransportType enum
        labels.add("3600")
        labels.add("7200")
        labels.add("14400")

        overTimeLabels.value = labels
        for ((index, value) in labels.withIndex()) {
            if (value.toInt() == account.params.expires) {
                overTimeIndex.value = index
                break
            }
        }
    }
}
